﻿#include "card_reader_plugin.h"

#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>
#include <Windows.h>
#include <string>
#include <memory>
#include "../native/hc_icrf.h"
#include <sstream>

namespace {
    class CardReaderPlugin : public flutter::Plugin {
    public:
        static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);

        CardReaderPlugin() {}

        virtual ~CardReaderPlugin() {}

    private:
        void HandleMethodCall(
                const flutter::MethodCall <flutter::EncodableValue> &method_call,
                std::unique_ptr <flutter::MethodResult<flutter::EncodableValue>> result);

        // 添加日志函数
        void SendLog(const std::string &message);

        // 保存channel引用用于发送日志
        std::unique_ptr <flutter::MethodChannel<flutter::EncodableValue>> channel_;

        // 保存设备句柄供其他方法使用
        HANDLE device_handle_;
    };

    // 添加日志发送函数
    void CardReaderPlugin::SendLog(const std::string &message) {
        if (channel_) {
            channel_->InvokeMethod("log", std::make_unique<flutter::EncodableValue>(message));
        }
    }

    void CardReaderPlugin::RegisterWithRegistrar(
            flutter::PluginRegistrarWindows *registrar) {
        auto channel = std::make_unique < flutter::MethodChannel < flutter::EncodableValue >> (
                registrar->messenger(), "card_reader",
                        &flutter::StandardMethodCodec::GetInstance());
        auto plugin = std::make_unique<CardReaderPlugin>();
        // 保存channel引用
        plugin->channel_ = std::make_unique < flutter::MethodChannel < flutter::EncodableValue >> (
                registrar->messenger(), "card_reader",
                        &flutter::StandardMethodCodec::GetInstance());

        plugin->channel_->SetMethodCallHandler(
                [plugin_pointer = plugin.get()](const auto &call, auto result) {
                    plugin_pointer->HandleMethodCall(call, std::move(result));
                });
        registrar->AddPlugin(std::move(plugin));
    }

    void CardReaderPlugin::HandleMethodCall(
            const flutter::MethodCall <flutter::EncodableValue> &method_call,
            std::unique_ptr <flutter::MethodResult<flutter::EncodableValue>> result) {
        const std::string &method = method_call.method_name();
        SendLog("method_call() ---> " + method_call.method_name());

        if (method == "open") {
            // 默认 USB 口 100
            HANDLE h = hc_init(100, 0);
            if (reinterpret_cast<intptr_t>(h) < 0) {
                result->Error("OPEN_FAILED", "无法打开读卡器");
            } else {
                device_handle_ = h;
                // 把句柄转成 int64 传回 Dart
                result->Success(flutter::EncodableValue(reinterpret_cast<int64_t>(h)));
            }
            return;
        }

        if (method == "beep") {
            const auto *args = std::get_if<flutter::EncodableMap>(method_call.arguments());
            int time = std::get<int>(args->at(flutter::EncodableValue("time")));
            int ret = dv_beep(device_handle_, static_cast<short>(time));
            if (ret < 0) {
                result->Error("BEEP_FAILED", "蜂鸣失败");
            } else {
                result->Success(flutter::EncodableValue(1));
            }
            return;
        }

        if (method == "readUid") {
            SendLog("readCard start");

            // 1. 请求
            unsigned short tagType = 0;
            int st = rf_request(device_handle_, 1, &tagType);
            if (st != 0) {
                SendLog("rf_request failed!");
                result->Error("READ_UID_FAILED", "rf_request 失败");
                return;
            }
            SendLog("1 rf_request success!");

            // 2. 防冲突
            unsigned long snr = 0;
            int st1 = rf_anticoll(device_handle_, 0, &snr);
            if (st1 != 0) {
                SendLog("rf_anticoll failed!");
                result->Error("READ_UID_FAILED", "rf_anticoll 失败");
                return;
            }

            // 格式化UID为16进制字符串 (需要转换字节序)
            char uidStr[9]; // 8字符 + null终止符
            // 将snr的字节序进行转换
            unsigned long reversedSnr = ((snr & 0xFF) << 24) |
                                        (((snr >> 8) & 0xFF) << 16) |
                                        (((snr >> 16) & 0xFF) << 8) |
                                        ((snr >> 24) & 0xFF);
            sprintf_s(uidStr, "%08X", reversedSnr);
            SendLog("2 rf_anticoll success! UID: " + std::string(uidStr));

            // 3. 选卡
            unsigned char size = 0;
            int st2 = rf_select(device_handle_, snr, &size);
            if (st2 != 0) {
                SendLog("rf_select failed!");
                result->Error("READ_UID_FAILED", "rf_select 失败");
                return;
            }
            SendLog("3 rf_select success!");

            // 4. 校验密码 (使用默认密码ABCDEF0123456789)
            unsigned char key[6] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}; // 默认密码
            unsigned char sector = 1; // 扇区1
            // 使用正确的函数rf_authentication_key，参数是扇区号而不是块号
            int st3 = rf_authentication_key(device_handle_, 0, sector * 4 + 1, key);
            if (st3 != 0) {
                SendLog("rf_authentication failed!");
                result->Error("READ_UID_FAILED", "rf_authentication 失败");
                return;
            }
            SendLog("4 rf_authentication success!");

            // 5. 读取数据 (从第5块开始读取)
            char data[33]; // 32个字符 + null终止符
            unsigned char block = 5;
            int st4 = rf_read_hex(device_handle_, block, data);
            if (st4 < 0) {
                SendLog("rf_read failed!");
                result->Error("READ_UID_FAILED", "rf_read 失败");
                return;
            }
            data[32] = '\0'; // 确保字符串终止
            SendLog("5 rf_read success! Data: " + std::string(data));

            // 蜂鸣
            dv_beep(device_handle_, 30);

            // 准备返回结果 (UID和读取的数据)
            flutter::EncodableMap resultMap;
            resultMap[flutter::EncodableValue("uid")] = flutter::EncodableValue(std::string(uidStr));
            resultMap[flutter::EncodableValue("data")] = flutter::EncodableValue(std::string(data));

            // 关闭设备
            hc_exit(device_handle_);

            result->Success(flutter::EncodableValue(resultMap));
            return;
        }

        if (method == "close") {
            // 打印日志
            SendLog("close start");
            int ret = hc_exit(device_handle_);
            if (ret < 0) {
                result->Error("CLOSE_FAILED", "关闭读卡器失败");
            } else {
                result->Success(flutter::EncodableValue(1));
            }
            return;
        }

        result->NotImplemented();
    }
}  // namespace

// 导出符号供 Flutter 引擎加载
//void CardReaderPluginRegisterWithRegistrar(
//        FlutterDesktopPluginRegistrarRef registrar) {
//    CardReaderPlugin::RegisterWithRegistrar(
//            flutter::PluginRegistrarManager::GetInstance()
//                    ->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
//}

// 确保这一行有 __declspec(dllexport)
extern "C" __declspec(dllexport) void CardReaderPluginRegisterWithRegistrar(
        FlutterDesktopPluginRegistrarRef registrar) {
    CardReaderPlugin::RegisterWithRegistrar(
            flutter::PluginRegistrarManager::GetInstance()
                    ->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
}
